package guild

import (
	"context"
	"fmt"
	"github.com/gogf/gf/v2/os/gmlock"
	"sort"
	"time"
	"xr-game-server/core/constants/cmd"
	"xr-game-server/core/constants/common"
	"xr-game-server/core/httpserver"
	"xr-game-server/core/lambda"
	"xr-game-server/core/push"
	"xr-game-server/dao/guilddao"
	"xr-game-server/dao/roledao"
	"xr-game-server/dto/guilddto"
	"xr-game-server/entity"
	"xr-game-server/errercode"
)

// JoinGuild 申请加入公会
func JoinGuild(ctx context.Context, reqData *guilddto.GuildJoinReq) (bool, error) {
	// 获取当前用户角色
	roleId := httpserver.GetAuthId(ctx)
	// 检查角色是否已加入公会
	roleEntity := roledao.GetRoleByRole(roleId)
	if roleEntity.GuildId > common.Zero {
		return false, errercode.CreateCode(errercode.GuildExist)
	}
	lockKey := fmt.Sprintf(GuildLock, roleEntity.GuildId)
	defer gmlock.Unlock(lockKey)
	lockFlag := gmlock.TryLock(lockKey)
	if !lockFlag {
		return false, errercode.CreateCode(errercode.SysBuyLimit)
	}
	guildData := guilddao.GetGuild(reqData.GuildId)
	//公会长，刷新审批列表
	members := guilddao.GetGuildMembers(reqData.GuildId)
	if guildData.AutoPass {
		//检查成员数量
		maxNum := 100
		if len(members) >= maxNum {
			return false, errercode.CreateCode(errercode.GuildFull)
		}
		memberData := entity.NewGuildMember(reqData.GuildId, roleId)
		guilddao.AddMember(memberData)
		roleEntity.SetGuildId(reqData.GuildId)
		memberData.SetTitle(entity.GuildMemberTitleMember)

		//排序
		members = guilddao.GetGuildMembers(reqData.GuildId)
		sort.Sort(MemberByUpdateAt(members))
	} else {

		//判断一下申请数量是否超过最大数量
		apples := guilddao.GetApply(reqData.GuildId)
		//判断是否超过最大数量
		if len(apples) >= 100 {
			return false, errercode.CreateCode(errercode.GuildApplyNumMax)
		}
		//判断是否已经申请
		if lambda.AnyMatch(apples, func(guildMember *entity.GuildApplication) bool {
			return guildMember.RoleId == roleId
		}) {
			//判断是否已经申请
			return false, errercode.CreateCode(errercode.GuildApplyExist)
		}
		blackList := guilddao.GetBlackListBy(reqData.GuildId, roleId)
		//判断是否拉黑
		if blackList.IsBlackList() {
			//拉黑时间多少毫秒
			return false, errercode.CreateCodeAndParam(errercode.GuildApplyBlack, blackList.BlackTime.Sub(time.Now()).Milliseconds())
		}
		// 创建申请
		applyData := entity.NewGuildApplication(reqData.GuildId, roleId)
		guilddao.AddApply(applyData)
		masterCache := guilddao.GetApply(reqData.GuildId)
		sort.Sort(ApplyByUpdateAt(masterCache))
	}
	members = guilddao.GetGuildMembers(reqData.GuildId)
	for _, val := range members {
		if val.Title != entity.GuildMemberTitleMember {
			push.OutData(val.RoleId, cmd.ApplyGuild)
		}

	}
	return true, nil
}
